/*
 * UNIVERSIDAD DEL VALLE DE GUATEMALA
 * ALGORITMOS Y ESTRUCTURAS DE DATOS, SECCION 20
 * JAVIER IVAN CASTILLO RIVERA, 11010
 * DESCRIPCION: Este programa consiste en una calculadora en formato postfix. Permite ingresar ecuaciones en este formato
 * y devuelve el resultado adecuado.  
 */



/*
 * IMPORTACION DE LIBREREIAS PARA EL VECTOR Y PARA INGRESAR DATOS
 */

import java.util.*;

public class CalculatorJavier 
{
	
	public static void main(String[] args) 
	{
		/*
		 * DECLARACION DE VARIABLES. OPERAND SON LOS OPERANDOS. ECUATION ES EL TEXTO QUE INGRESA EL USUARIO. RESPONSE ES LA RESPUESTA
		 * A LA PREGUNTA FINAL SI SEGUIR O NO UTILIZANDO LA CALCULADORA
		 */
		String Operand = "", Ecuation = "", Response = "";
		Scanner Info = new Scanner(System.in);
		int NumberOne, NumberTwo, Result = 0;
		/*
		 * CREACION DE OBJETO TIPO VECTORJAVIER PARA PODER UTILIZAR LAS FUNCIONES DEL STACK
		 */
		VectorJavier<String> stack = new VectorJavier<String>();
		boolean Error = false;
		
		/*
		 * CICLO DO-WHILE PARA UTILIZAR LA CALCULADORA MIENTRAS EL USUARIO LO PIDA.
		 */
		do{
			/*
			 * PRINTLN PARA EL ENCABEZADO DE LA CALCULADORA. 
			 */
			System.out.println("**** CALCULADORA FORMATO POSTIFIX ****");
			System.out.println("INGRESE LA OPERACION QUE DESEA REALIZAR. (DEBE INGRESARLA EN FORMATO POSTFIX): ");
			/*
			 * VARIABLE DONDE SE GUARDA EL TEXTO INGRESADO POR EL USUARIO. AQUI TAMBIEN SE DIVIDE EL TEXTO
			 * EN CADA ESPACIO " " QUE EXISTE. SE PARTA LA CADENA LAS VECES QUE HAY UN ESPACIO.
			 */
			Ecuation = Info.nextLine();
			String[] Data = Ecuation.split(" ");
			/*
			 * FOR PARA PODER GUARDAR INFORMACION EN EL STACK. AQUI SE UTILIZAN LOS METODOS DEL STACK
			 * ADEMÁS SE VA EVALUANDO LO INGRESADO Y EFECTUANDOLO. ESTE ES LA PARTE DE LA CALCULADORA.  
			 */
			for(int i = 0; i < Data.length;i++)
			{
				Operand = Data[i];
				/*
				 * CONDICION IF PARA VERIFICAR QUE SI SE INGRESO UN OPERANDO O UN OPERADOR. 
				 * SI INGRESO OPERADOR SE VERIFICA QUE HAYA SUFICIENTES OPERANDOS EN LA PILA SI NO MUESTRA ERROR. 
				 * SI NO HAY PROBLEMAS ENTONCES EFECTUA EL CALCULO Y GUARDA EL RESULTADO EN EL STACK. 
				 */
				if((Operand.equals("+"))||(Operand.equals("-"))||(Operand.equals("*"))||(Operand.equals("/")))
				{
					if(stack.size()!=2)
					{
						System.out.println("ERROR, NO HA INGRESADO EL NUMERO ADECUADO DE OPERANDOS. NO SE PUEDE OPERAR DE ESTA FORMA.");
						Error = true;
						i = Data.length;
					}
					else
					{
						/*
						 * TRY - CATCH POR SI SE INGRESA LETRAS EN LUGAR DE NUMEROS
						 */

						try{
							/*
							 * AQUI SE OBTIENE DOS OPERANDOS Y SE EFECTUA LA OPERACION CORRESPONDIENTE
							 */
							NumberTwo = Integer.parseInt(stack.pop());
							NumberOne = Integer.parseInt(stack.pop());
							if(Operand.equals("+"))
							{
								Result = NumberOne + NumberTwo;
								stack.push(Result+"");
							}
							if(Operand.equals("-"))
							{
								Result = NumberOne - NumberTwo;
								stack.push(Result+"");
							}
							if(Operand.equals("*"))
							{
								Result = NumberOne * NumberTwo;
								stack.push(Result+"");
							}
							if(Operand.equals("/"))
							{
								if (NumberTwo!=0)
								{
									Result = NumberOne / NumberTwo;
									stack.push(Result+"");	
								}
								/*
								 * DEFENSIVA PARA DIVISION ENTRE CERO.
								 */
								else
								{
									System.out.println("ERROR, NO EXISTE LA DIVISION ENTRE 0 PORFAVOR REVISE LO INGRESADO");
									Error = true;
									i = Data.length;
								}
								
							}

						}catch(Exception e){
							System.out.println("ERROR, NO INGRESO EL OPERANDO ADECUADO");
							Error = true;
						}
											}
				}
				else
				{
					Operand = (String)Data[i];
					stack.push(Operand);		
				}
			}
			/*
			 * SI NO HABIA ERRORES EN EL PROGRAMA ENTONCES MUESTRA LA RESPUESTAS SI SÍ LOS HABIAN ENTONCES
			 * NO MUESTRA LA RESPUESTA.
			 */
			if(!Error)
			{
				System.out.println("LA RESPUESTA DE: " + Ecuation + " ES: ");
				System.out.println(Result);				
			}
			/*
			 * SE BORRA EL CONTENIDO DEL STACK PARA PODER SER UTILIZADO CUANDO INGRESE INFORMACION NUEVAMENTE.
			 */
			for (int j = 0; j < stack.size(); j++)
			{
				stack.pop();
			}
			System.out.println("DESEA UTILIZAR LA CALCULADORA NUEVAMENTE? (SI O NO): ");
			Response = Info.nextLine();
			while(!Response.equalsIgnoreCase("SI")&&!Response.equalsIgnoreCase("NO"))
			{
				System.out.println("NO INGRESO UNA OPCION VALIDA. ");
				System.out.println("DESEA UTILIZAR LA CALCULADORA NUEVAMENTE? (SI O NO): ");
				Response = Info.nextLine();
			}
			Error = false;
			
		}while(Response.equalsIgnoreCase("SI"));
		
		System.out.println("*** GRACIAS POR SU PARTICIPACION!! ***");
				
	}

}

